home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / doom / quake1.zip / ANTICAMP.ZIP / ITEMS.QC < prev    next >
Text File  |  1996-10-02  |  33KB  |  1,475 lines

  1. void() W_SetCurrentAmmo;
  2. /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
  3. BE .8 .3 .4 IN COLOR */
  4.  
  5.  
  6. void() SUB_regen =
  7. {
  8.     self.model = self.mdl;        // restore original model
  9.     self.solid = SOLID_TRIGGER;    // allow it to be touched again
  10.  
  11. //#Harlequin#  Next line disables item respawn noises for camper-sensitive stuff
  12.     if ((deathmatch != 1) || (self.think != ItemFindCampers))
  13.         sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);    // play respawn sound
  14.     setorigin (self, self.origin);
  15. };
  16.  
  17.  
  18.  
  19. /*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
  20. prints a warning message when spawned
  21. */
  22. void() noclass =
  23. {
  24.     dprint ("noclass spawned at");
  25.     dprint (vtos(self.origin));
  26.     dprint ("\n");
  27.     remove (self);
  28. };
  29.  
  30.  
  31.  
  32. /*
  33. ============
  34. PlaceItem
  35.  
  36. plants the object on the floor
  37. ============
  38. */
  39. void() PlaceItem =
  40. {
  41. //#Harlequin#  These are the settings to tell the game which items are
  42. //camper-sensitive.  1 = sensitive, 0 = not sensitive.  If you want to
  43. //sensitize items not listed here, code it your own damn self :-).
  44.     local float RED_ARMOR_SENSITIVE = 1;
  45.     local float YELLOW_ARMOR_SENSITIVE = 0;
  46.     local float GREEN_ARMOR_SENSITIVE = 0;
  47.  
  48.     local float ROCKET_LAUNCHER_SENSITIVE = 1;
  49.     local float GRENADE_LAUNCHER_SENSITIVE = 1;
  50.     local float LIGHTNING_GUN_SENSITIVE = 1;
  51.     local float HEAVY_NAILGUN_SENSITIVE = 0;
  52.     local float NAILGUN_SENSITIVE = 0;
  53.     local float SUPER_SHOTGUN_SENSITIVE = 0;
  54.  
  55.     local float QUAD_SENSITIVE = 1;
  56.     local float PENTAGRAM_SENSITIVE = 0;  // this thing takes 5 mins to respawn!
  57.     local float RING_SENSITIVE = 0;      // so does this one
  58.  
  59. //    local float AXE_SENSITIVE = 1;      // just kidding ;-)
  60.  
  61.     local float    oldz;
  62.  
  63.     self.mdl = self.model;        // so it can be restored on respawn
  64.     self.flags = FL_ITEM;        // make extra wide
  65.     self.solid = SOLID_TRIGGER;
  66.     self.movetype = MOVETYPE_TOSS;    
  67.     self.velocity = '0 0 0';
  68.     self.origin_z = self.origin_z + 6;
  69.     oldz = self.origin_z;
  70.     if (!droptofloor())
  71.     {
  72.         dprint ("Bonus item fell out of level at ");
  73.         dprint (vtos(self.origin));
  74.         dprint ("\n");
  75.         remove(self);
  76.         return;
  77.     }
  78.  
  79. //#Harlequin#  Initializes camper-detecting items.  Think times are staggered to improve speed.
  80.     if (deathmatch == 1)
  81.     {
  82. //#Harlequin#  CAMPPOS is how the item identifies itself in warnings.
  83.         if ((self.classname == "item_armorInv") && RED_ARMOR_SENSITIVE)
  84.         {
  85.             self.think = ItemFindCampers;
  86.             self.nextthink = time + random() + random() + random() + random();
  87.             self.CAMPPOS = "RED ARMOR";
  88.         }
  89.         if ((self.classname == "item_armor2") && YELLOW_ARMOR_SENSITIVE)
  90.         {
  91.             self.think = ItemFindCampers;
  92.             self.nextthink = time + random() + random() + random() + random();
  93.             self.CAMPPOS = "YELLOW ARMOR";
  94.         }
  95.         if ((self.classname == "item_armor1") && GREEN_ARMOR_SENSITIVE)
  96.         {
  97.             self.think = ItemFindCampers;
  98.             self.nextthink = time + random() + random() + random() + random();
  99.             self.CAMPPOS = "GREEN ARMOR";
  100.         }
  101.  
  102.         if ((self.classname == "item_artifact_super_damage") && QUAD_SENSITIVE)
  103.         {
  104.             self.think = ItemFindCampers;
  105.             self.nextthink = time + random() + random() + random() + random();
  106.             self.CAMPPOS = "QUAD DAMAGE";
  107.         }
  108.         if ((self.classname == "item_artifact_invisibility") && RING_SENSITIVE)
  109.         {
  110.             self.think = ItemFindCampers;
  111.             self.nextthink = time + random() + random() + random() + random();
  112.             self.CAMPPOS = "RING OF SHADOWS";
  113.         }
  114.         if ((self.classname == "item_artifact_invulnerability") && PENTAGRAM_SENSITIVE)
  115.         {
  116.             self.think = ItemFindCampers;
  117.             self.nextthink = time + random() + random() + random() + random();
  118.             self.CAMPPOS = "PENTAGRAM";
  119.         }
  120.  
  121.         if ((self.classname == "weapon_rocketlauncher") && ROCKET_LAUNCHER_SENSITIVE)
  122.         {
  123.             self.think = ItemFindCampers;
  124.             self.nextthink = time + random() + random() + random() + random();
  125.             self.CAMPPOS = "ROCKET LAUNCHER";
  126.         }
  127.         if ((self.classname == "weapon_supernailgun") && HEAVY_NAILGUN_SENSITIVE)
  128.         {
  129.             self.think = ItemFindCampers;
  130.             self.nextthink = time + random() + random() + random() + random();
  131.             self.CAMPPOS = "HEAVY NAILGUN";
  132.         }
  133.         if ((self.classname == "weapon_nailgun") && NAILGUN_SENSITIVE)
  134.         {
  135.             self.think = ItemFindCampers;
  136.             self.nextthink = time + random() + random() + random() + random();
  137.             self.CAMPPOS = "NAILGUN";
  138.         }
  139.         if ((self.classname == "weapon_supershotgun") && SUPER_SHOTGUN_SENSITIVE)
  140.         {
  141.             self.think = ItemFindCampers;
  142.             self.nextthink = time + random() + random() + random() + random();
  143.             self.CAMPPOS = "SUPER SHOTGUN";
  144.         }
  145.         if ((self.classname == "weapon_grenadelauncher") && GRENADE_LAUNCHER_SENSITIVE)
  146.         {
  147.             self.think = ItemFindCampers;
  148.             self.nextthink = time + random() + random() + random() + random();
  149.             self.CAMPPOS = "GRENADE LAUNCHER";
  150.         }
  151.         if ((self.classname == "weapon_lightning") && LIGHTNING_GUN_SENSITIVE)
  152.         {
  153.             self.think = ItemFindCampers;
  154.             self.nextthink = time + random() + random() + random() + random();
  155.             self.CAMPPOS = "LIGHTNING GUN";
  156.         }
  157.     }
  158. //#Harlequin#  End of my mods in this section
  159. };
  160.  
  161.  
  162. /*
  163. ============
  164. StartItem
  165.  
  166. Sets the clipping size and plants the object on the floor
  167. ============
  168. */
  169. void() StartItem =
  170. {
  171.     self.nextthink = time + 0.2;    // items start after other solids
  172.     self.think = PlaceItem;
  173. };
  174.  
  175. /*
  176. =========================================================================
  177.  
  178. HEALTH BOX
  179.  
  180. =========================================================================
  181. */
  182. //
  183. // T_Heal: add health to an entity, limiting health to max_health
  184. // "ignore" will ignore max_health limit
  185. //
  186. float (entity e, float healamount, float ignore) T_Heal =
  187. {
  188.     if (e.health <= 0)
  189.         return 0;
  190.     if ((!ignore) && (e.health >= other.max_health))
  191.         return 0;
  192.     healamount = ceil(healamount);
  193.  
  194.     e.health = e.health + healamount;
  195.     if ((!ignore) && (e.health >= other.max_health))
  196.         e.health = other.max_health;
  197.         
  198.     if (e.health > 250)
  199.         e.health = 250;
  200.     return 1;
  201. };
  202.  
  203. /*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth
  204. Health box. Normally gives 25 points.
  205. Rotten box heals 5-10 points,
  206. megahealth will add 100 health, then 
  207. rot you down to your maximum health limit, 
  208. one point per second.
  209. */
  210.  
  211. float    H_ROTTEN = 1;
  212. float    H_MEGA = 2;
  213. .float    healamount, healtype;
  214. void() health_touch;
  215. void() item_megahealth_rot;
  216.  
  217. void() item_health =
  218. {    
  219.     self.touch = health_touch;
  220.  
  221.     if (self.spawnflags & H_ROTTEN)
  222.     {
  223.         precache_model("maps/b_bh10.bsp");
  224.  
  225.         precache_sound("items/r_item1.wav");
  226.         setmodel(self, "maps/b_bh10.bsp");
  227.         self.noise = "items/r_item1.wav";
  228.         self.healamount = 15;
  229.         self.healtype = 0;
  230.     }
  231.     else
  232.     if (self.spawnflags & H_MEGA)
  233.     {
  234.         precache_model("maps/b_bh100.bsp");
  235.         precache_sound("items/r_item2.wav");
  236.         setmodel(self, "maps/b_bh100.bsp");
  237.         self.noise = "items/r_item2.wav";
  238.         self.healamount = 100;
  239.         self.healtype = 2;
  240.     }
  241.     else
  242.     {
  243.         precache_model("maps/b_bh25.bsp");
  244.         precache_sound("items/health1.wav");
  245.         setmodel(self, "maps/b_bh25.bsp");
  246.         self.noise = "items/health1.wav";
  247.         self.healamount = 25;
  248.         self.healtype = 1;
  249.     }
  250.     setsize (self, '0 0 0', '32 32 56');
  251.     StartItem ();
  252. };
  253.  
  254.  
  255. void() health_touch =
  256. {
  257.     local    float amount;
  258.     local    string    s;
  259.     
  260.     if (other.classname != "player")
  261.         return;
  262.     
  263.     if (self.healtype == 2) // Megahealth?  Ignore max_health...
  264.     {
  265.         if (other.health >= 250)
  266.             return;
  267.         if (!T_Heal(other, self.healamount, 1))
  268.             return;
  269.     }
  270.     else
  271.     {
  272.         if (!T_Heal(other, self.healamount, 0))
  273.             return;
  274.     }
  275.     
  276.     sprint(other, "You receive ");
  277.     s = ftos(self.healamount);
  278.     sprint(other, s);
  279.     sprint(other, " health\n");
  280.     
  281. // health touch sound
  282.     sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  283.  
  284.     stuffcmd (other, "bf\n");
  285.     
  286.     self.model = string_null;
  287.     self.solid = SOLID_NOT;
  288.  
  289.     // Megahealth = rot down the player's super health
  290.     if (self.healtype == 2)
  291.     {
  292.         other.items = other.items | IT_SUPERHEALTH;
  293.         self.nextthink = time + 5;
  294.         self.think = item_megahealth_rot;
  295.         self.owner = other;
  296.     }
  297.     else
  298.     {
  299.         if (deathmatch != 2)        // deathmatch 2 is the silly old rules
  300.         {
  301.             if (deathmatch)
  302.                 self.nextthink = time + 20;
  303.             self.think = SUB_regen;
  304.         }
  305.     }
  306.     
  307.     activator = other;
  308.     SUB_UseTargets();                // fire all targets / killtargets
  309. };    
  310.  
  311. void() item_megahealth_rot =
  312. {
  313.     other = self.owner;
  314.     
  315.     if (other.health > other.max_health)
  316.     {
  317.         other.health = other.health - 1;
  318.         self.nextthink = time + 1;
  319.         return;
  320.     }
  321.  
  322. // it is possible for a player to die and respawn between rots, so don't
  323. // just blindly subtract the flag off
  324.     other.items = other.items - (other.items & IT_SUPERHEALTH);
  325.     
  326.     if (deathmatch == 1)    // deathmatch 2 is silly old rules
  327.     {
  328.         self.nextthink = time + 20;
  329.         self.think = SUB_regen;
  330.     }
  331. };
  332.  
  333. /*
  334. ===============================================================================
  335.  
  336. ARMOR
  337.  
  338. ===============================================================================
  339. */
  340.  
  341. void() armor_touch;
  342.  
  343. void() armor_touch =
  344. {
  345.     local    float    type, value, bit;
  346.     
  347.     if (other.health <= 0)
  348.         return;
  349.     if (other.classname != "player")
  350.         return;
  351.  
  352.     if (self.classname == "item_armor1")
  353.     {
  354.         type = 0.3;
  355.         value = 100;
  356.         bit = IT_ARMOR1;
  357.     }
  358.     if (self.classname == "item_armor2")
  359.     {
  360.         type = 0.6;
  361.         value = 150;
  362.         bit = IT_ARMOR2;
  363.     }
  364.     if (self.classname == "item_armorInv")
  365.     {
  366.         type = 0.8;
  367.         value = 200;
  368.         bit = IT_ARMOR3;
  369.     }
  370.     if (other.armortype*other.armorvalue >= type*value)
  371.         return;
  372.         
  373.     other.armortype = type;
  374.     other.armorvalue = value;
  375.     other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  376.  
  377.     self.solid = SOLID_NOT;
  378.     self.model = string_null;
  379.  
  380. //#Harlequin#  Armor respawn time
  381.     if ((deathmatch == 1) && (self.think == ItemFindCampers))
  382.         self.RESPAWN_TIME = time + 20;
  383.  
  384.     else if (deathmatch == 1)
  385.     {
  386.         self.nextthink = time + 20;
  387.         self.think = SUB_regen;
  388.     }
  389. //#Harlequin#  End of my mods in this section
  390.  
  391.     sprint(other, "You got armor\n");
  392. // armor touch sound
  393.     sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  394.     stuffcmd (other, "bf\n");
  395.     
  396.     activator = other;
  397.     SUB_UseTargets();                // fire all targets / killtargets
  398. };
  399.  
  400.  
  401. /*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)
  402. */
  403.  
  404. void() item_armor1 =
  405. {
  406.     self.touch = armor_touch;
  407.     precache_model ("progs/armor.mdl");
  408.     setmodel (self, "progs/armor.mdl");
  409.     self.skin = 0;
  410.     setsize (self, '-16 -16 0', '16 16 56');
  411.     StartItem ();
  412. };
  413.  
  414. /*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32)
  415. */
  416.  
  417. void() item_armor2 =
  418. {
  419.     self.touch = armor_touch;
  420.     precache_model ("progs/armor.mdl");
  421.     setmodel (self, "progs/armor.mdl");
  422.     self.skin = 1;
  423.     setsize (self, '-16 -16 0', '16 16 56');
  424.     StartItem ();
  425. };
  426.  
  427. /*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32)
  428. */
  429.  
  430. void() item_armorInv =
  431. {
  432.     self.touch = armor_touch;
  433.     precache_model ("progs/armor.mdl");
  434.     setmodel (self, "progs/armor.mdl");
  435.     self.skin = 2;
  436.     setsize (self, '-16 -16 0', '16 16 56');
  437.     StartItem ();
  438. };
  439.  
  440. /*
  441. ===============================================================================
  442.  
  443. WEAPONS
  444.  
  445. ===============================================================================
  446. */
  447.  
  448. void() bound_other_ammo =
  449. {
  450.     if (other.ammo_shells > 100)
  451.         other.ammo_shells = 100;
  452.     if (other.ammo_nails > 200)
  453.         other.ammo_nails = 200;
  454.     if (other.ammo_rockets > 100)
  455.         other.ammo_rockets = 100;        
  456.     if (other.ammo_cells > 100)
  457.         other.ammo_cells = 100;        
  458. };
  459.  
  460.  
  461. float(float w) RankForWeapon =
  462. {
  463.     if (w == IT_LIGHTNING)
  464.         return 1;
  465.     if (w == IT_ROCKET_LAUNCHER)
  466.         return 2;
  467.     if (w == IT_SUPER_NAILGUN)
  468.         return 3;
  469.     if (w == IT_GRENADE_LAUNCHER)
  470.         return 4;
  471.     if (w == IT_SUPER_SHOTGUN)
  472.         return 5;
  473.     if (w == IT_NAILGUN)
  474.         return 6;
  475.     return 7;
  476. };
  477.  
  478. /*
  479. =============
  480. Deathmatch_Weapon
  481.  
  482. Deathmatch weapon change rules for picking up a weapon
  483.  
  484. .float        ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
  485. =============
  486. */
  487. void(float old, float new) Deathmatch_Weapon =
  488. {
  489.     local float or, nr;
  490.  
  491. // change self.weapon if desired
  492.     or = RankForWeapon (self.weapon);
  493.     nr = RankForWeapon (new);
  494.     if ( nr < or )
  495.         self.weapon = new;
  496. };
  497.  
  498. /*
  499. =============
  500. weapon_touch
  501. =============
  502. */
  503. float() W_BestWeapon;
  504.  
  505. void() weapon_touch =
  506. {
  507.     local    float    hadammo, best, new, old;
  508.     local    entity    stemp;
  509.     local    float    leave;
  510.  
  511.     if (!(other.flags & FL_CLIENT))
  512.         return;
  513.  
  514. // if the player was using his best weapon, change up to the new one if better        
  515.     stemp = self;
  516.     self = other;
  517.     best = W_BestWeapon();
  518.     self = stemp;
  519.  
  520.     if (deathmatch == 2 || coop)
  521.         leave = 1;
  522.     else
  523.         leave = 0;
  524.     
  525.     if (self.classname == "weapon_nailgun")
  526.     {
  527.         if (leave && (other.items & IT_NAILGUN) )
  528.             return;
  529.         hadammo = other.ammo_nails;            
  530.         new = IT_NAILGUN;
  531.         other.ammo_nails = other.ammo_nails + 30;
  532.     }
  533.     else if (self.classname == "weapon_supernailgun")
  534.     {
  535.         if (leave && (other.items & IT_SUPER_NAILGUN) )
  536.             return;
  537.         hadammo = other.ammo_rockets;            
  538.         new = IT_SUPER_NAILGUN;
  539.         other.ammo_nails = other.ammo_nails + 30;
  540.     }
  541.     else if (self.classname == "weapon_supershotgun")
  542.     {
  543.         if (leave && (other.items & IT_SUPER_SHOTGUN) )
  544.             return;
  545.         hadammo = other.ammo_rockets;            
  546.         new = IT_SUPER_SHOTGUN;
  547.         other.ammo_shells = other.ammo_shells + 5;
  548.     }
  549.     else if (self.classname == "weapon_rocketlauncher")
  550.     {
  551.         if (leave && (other.items & IT_ROCKET_LAUNCHER) )
  552.             return;
  553.         hadammo = other.ammo_rockets;            
  554.         new = IT_ROCKET_LAUNCHER;
  555.         other.ammo_rockets = other.ammo_rockets + 5;
  556.     }
  557.     else if (self.classname == "weapon_grenadelauncher")
  558.     {
  559.         if (leave && (other.items & IT_GRENADE_LAUNCHER) )
  560.             return;
  561.         hadammo = other.ammo_rockets;            
  562.         new = IT_GRENADE_LAUNCHER;
  563.         other.ammo_rockets = other.ammo_rockets + 5;
  564.     }
  565.     else if (self.classname == "weapon_lightning")
  566.     {
  567.         if (leave && (other.items & IT_LIGHTNING) )
  568.             return;
  569.         hadammo = other.ammo_rockets;            
  570.         new = IT_LIGHTNING;
  571.         other.ammo_cells = other.ammo_cells + 15;
  572.     }
  573.     else
  574.         objerror ("weapon_touch: unknown classname");
  575.  
  576.     sprint (other, "You got the ");
  577.     sprint (other, self.netname);
  578.     sprint (other, "\n");
  579. // weapon touch sound
  580.     sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  581.     stuffcmd (other, "bf\n");
  582.  
  583.     bound_other_ammo ();
  584.  
  585. // change to the weapon
  586.     old = other.items;
  587.     other.items = other.items | new;
  588.     
  589.     stemp = self;
  590.     self = other;
  591.  
  592.     if (!deathmatch)
  593.         self.weapon = new;
  594.     else
  595.         Deathmatch_Weapon (old, new);
  596.  
  597.     W_SetCurrentAmmo();
  598.  
  599.     self = stemp;
  600.  
  601.     if (leave)
  602.         return;
  603.  
  604. // remove it in single player, or setup for respawning in deathmatch
  605.     self.model = string_null;
  606.     self.solid = SOLID_NOT;
  607.  
  608.     if (deathmatch == 1)
  609.     {
  610. //#Harlequin#  Sets respawn times for "camper" weapons
  611.         if (self.think == ItemFindCampers)
  612.             self.RESPAWN_TIME = time + 30;
  613.         else
  614.         {
  615.             self.nextthink = time + 30;
  616.             self.think = SUB_regen;
  617.         }
  618. //#Harlequin#  End of my mods in this section
  619.  
  620.     }
  621.     activator = other;
  622.     SUB_UseTargets();                // fire all targets / killtargets
  623. };
  624.  
  625.  
  626. /*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
  627. */
  628.  
  629. void() weapon_supershotgun =
  630. {
  631.     precache_model ("progs/g_shot.mdl");
  632.     setmodel (self, "progs/g_shot.mdl");
  633.     self.weapon = IT_SUPER_SHOTGUN;
  634.     self.netname = "Double-barrelled Shotgun";
  635.     self.touch = weapon_touch;
  636.     setsize (self, '-16 -16 0', '16 16 56');
  637.     StartItem ();
  638. };
  639.  
  640. /*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  641. */
  642.  
  643. void() weapon_nailgun =
  644. {
  645.     precache_model ("progs/g_nail.mdl");
  646.     setmodel (self, "progs/g_nail.mdl");
  647.     self.weapon = IT_NAILGUN;
  648.     self.netname = "nailgun";
  649.     self.touch = weapon_touch;
  650.     setsize (self, '-16 -16 0', '16 16 56');
  651.     StartItem ();
  652. };
  653.  
  654. /*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  655. */
  656.  
  657. void() weapon_supernailgun =
  658. {
  659.     precache_model ("progs/g_nail2.mdl");
  660.     setmodel (self, "progs/g_nail2.mdl");
  661.     self.weapon = IT_SUPER_NAILGUN;
  662.     self.netname = "Super Nailgun";
  663.     self.touch = weapon_touch;
  664.     setsize (self, '-16 -16 0', '16 16 56');
  665.     StartItem ();
  666. };
  667.  
  668. /*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  669. */
  670.  
  671. void() weapon_grenadelauncher =
  672. {
  673.     precache_model ("progs/g_rock.mdl");
  674.     setmodel (self, "progs/g_rock.mdl");
  675.     self.weapon = 3;
  676.     self.netname = "Grenade Launcher";
  677.     self.touch = weapon_touch;
  678.     setsize (self, '-16 -16 0', '16 16 56');
  679.     StartItem ();
  680. };
  681.  
  682. /*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  683. */
  684.  
  685. void() weapon_rocketlauncher =
  686. {
  687.     precache_model ("progs/g_rock2.mdl");
  688.     setmodel (self, "progs/g_rock2.mdl");
  689.     self.weapon = 3;
  690.     self.netname = "Rocket Launcher";
  691.     self.touch = weapon_touch;
  692.     setsize (self, '-16 -16 0', '16 16 56');
  693.     StartItem ();
  694. };
  695.  
  696.  
  697. /*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
  698. */
  699.  
  700. void() weapon_lightning =
  701. {
  702.     precache_model ("progs/g_light.mdl");
  703.     setmodel (self, "progs/g_light.mdl");
  704.     self.weapon = 3;
  705.     self.netname = "Thunderbolt";
  706.     self.touch = weapon_touch;
  707.     setsize (self, '-16 -16 0', '16 16 56');
  708.     StartItem ();
  709. };
  710.  
  711.  
  712. /*
  713. ===============================================================================
  714.  
  715. AMMO
  716.  
  717. ===============================================================================
  718. */
  719.  
  720. void() ammo_touch =
  721. {
  722. local entity    stemp;
  723. local float        best;
  724.  
  725.     if (other.classname != "player")
  726.         return;
  727.     if (other.health <= 0)
  728.         return;
  729.  
  730. // if the player was using his best weapon, change up to the new one if better        
  731.     stemp = self;
  732.     self = other;
  733.     best = W_BestWeapon();
  734.     self = stemp;
  735.  
  736.  
  737. // shotgun
  738.     if (self.weapon == 1)
  739.     {
  740.         if (other.ammo_shells >= 100)
  741.             return;
  742.         other.ammo_shells = other.ammo_shells + self.aflag;
  743.     }
  744.  
  745. // spikes
  746.     if (self.weapon == 2)
  747.     {
  748.         if (other.ammo_nails >= 200)
  749.             return;
  750.         other.ammo_nails = other.ammo_nails + self.aflag;
  751.     }
  752.  
  753. //    rockets
  754.     if (self.weapon == 3)
  755.     {
  756.         if (other.ammo_rockets >= 100)
  757.             return;
  758.         other.ammo_rockets = other.ammo_rockets + self.aflag;
  759.     }
  760.  
  761. //    cells
  762.     if (self.weapon == 4)
  763.     {
  764.         if (other.ammo_cells >= 200)
  765.             return;
  766.         other.ammo_cells = other.ammo_cells + self.aflag;
  767.     }
  768.  
  769.     bound_other_ammo ();
  770.     
  771.     sprint (other, "You got the ");
  772.     sprint (other, self.netname);
  773.     sprint (other, "\n");
  774. // ammo touch sound
  775.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  776.     stuffcmd (other, "bf\n");
  777.  
  778. // change to a better weapon if appropriate
  779.  
  780.     if ( other.weapon == best )
  781.     {
  782.         stemp = self;
  783.         self = other;
  784.         self.weapon = W_BestWeapon();
  785.         W_SetCurrentAmmo ();
  786.         self = stemp;
  787.     }
  788.  
  789. // if changed current ammo, update it
  790.     stemp = self;
  791.     self = other;
  792.     W_SetCurrentAmmo();
  793.     self = stemp;
  794.  
  795. // remove it in single player, or setup for respawning in deathmatch
  796.     self.model = string_null;
  797.     self.solid = SOLID_NOT;
  798.     if (deathmatch == 1)
  799.         self.nextthink = time + 30;
  800.     
  801.     self.think = SUB_regen;
  802.  
  803.     activator = other;
  804.     SUB_UseTargets();                // fire all targets / killtargets
  805. };
  806.  
  807.  
  808.  
  809.  
  810. float WEAPON_BIG2 = 1;
  811.  
  812. /*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big
  813. */
  814.  
  815. void() item_shells =
  816. {
  817.     self.touch = ammo_touch;
  818.  
  819.     if (self.spawnflags & WEAPON_BIG2)
  820.     {
  821.         precache_model ("maps/b_shell1.bsp");
  822.         setmodel (self, "maps/b_shell1.bsp");
  823.         self.aflag = 40;
  824.     }
  825.     else
  826.     {
  827.         precache_model ("maps/b_shell0.bsp");
  828.         setmodel (self, "maps/b_shell0.bsp");
  829.         self.aflag = 20;
  830.     }
  831.     self.weapon = 1;
  832.     self.netname = "shells";
  833.     setsize (self, '0 0 0', '32 32 56');
  834.     StartItem ();
  835. };
  836.  
  837. /*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big
  838. */
  839.  
  840. void() item_spikes =
  841. {
  842.     self.touch = ammo_touch;
  843.  
  844.     if (self.spawnflags & WEAPON_BIG2)
  845.     {
  846.         precache_model ("maps/b_nail1.bsp");
  847.         setmodel (self, "maps/b_nail1.bsp");
  848.         self.aflag = 50;
  849.     }
  850.     else
  851.     {
  852.         precache_model ("maps/b_nail0.bsp");
  853.         setmodel (self, "maps/b_nail0.bsp");
  854.         self.aflag = 25;
  855.     }
  856.     self.weapon = 2;
  857.     self.netname = "nails";
  858.     setsize (self, '0 0 0', '32 32 56');
  859.     StartItem ();
  860. };
  861.  
  862. /*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
  863. */
  864.  
  865. void() item_rockets =
  866. {
  867.     self.touch = ammo_touch;
  868.  
  869.     if (self.spawnflags & WEAPON_BIG2)
  870.     {
  871.         precache_model ("maps/b_rock1.bsp");
  872.         setmodel (self, "maps/b_rock1.bsp");
  873.         self.aflag = 10;
  874.     }
  875.     else
  876.     {
  877.         precache_model ("maps/b_rock0.bsp");
  878.         setmodel (self, "maps/b_rock0.bsp");
  879.         self.aflag = 5;
  880.     }
  881.     self.weapon = 3;
  882.     self.netname = "rockets";
  883.     setsize (self, '0 0 0', '32 32 56');
  884.     StartItem ();
  885. };
  886.  
  887.  
  888. /*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big
  889. */
  890.  
  891. void() item_cells =
  892. {
  893.     self.touch = ammo_touch;
  894.  
  895.     if (self.spawnflags & WEAPON_BIG2)
  896.     {
  897.         precache_model ("maps/b_batt1.bsp");
  898.         setmodel (self, "maps/b_batt1.bsp");
  899.         self.aflag = 12;
  900.     }
  901.     else
  902.     {
  903.         precache_model ("maps/b_batt0.bsp");
  904.         setmodel (self, "maps/b_batt0.bsp");
  905.         self.aflag = 6;
  906.     }
  907.     self.weapon = 4;
  908.     self.netname = "cells";
  909.     setsize (self, '0 0 0', '32 32 56');
  910.     StartItem ();
  911. };
  912.  
  913.  
  914. /*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big
  915. DO NOT USE THIS!!!! IT WILL BE REMOVED!
  916. */
  917.  
  918. float WEAPON_SHOTGUN = 1;
  919. float WEAPON_ROCKET = 2;
  920. float WEAPON_SPIKES = 4;
  921. float WEAPON_BIG = 8;
  922. void() item_weapon =
  923. {
  924.     self.touch = ammo_touch;
  925.  
  926.     if (self.spawnflags & WEAPON_SHOTGUN)
  927.     {
  928.         if (self.spawnflags & WEAPON_BIG)
  929.         {
  930.             precache_model ("maps/b_shell1.bsp");
  931.             setmodel (self, "maps/b_shell1.bsp");
  932.             self.aflag = 40;
  933.         }
  934.         else
  935.         {
  936.             precache_model ("maps/b_shell0.bsp");
  937.             setmodel (self, "maps/b_shell0.bsp");
  938.             self.aflag = 20;
  939.         }
  940.         self.weapon = 1;
  941.         self.netname = "shells";
  942.     }
  943.  
  944.     if (self.spawnflags & WEAPON_SPIKES)
  945.     {
  946.         if (self.spawnflags & WEAPON_BIG)
  947.         {
  948.             precache_model ("maps/b_nail1.bsp");
  949.             setmodel (self, "maps/b_nail1.bsp");
  950.             self.aflag = 40;
  951.         }
  952.         else
  953.         {
  954.             precache_model ("maps/b_nail0.bsp");
  955.             setmodel (self, "maps/b_nail0.bsp");
  956.             self.aflag = 20;
  957.         }
  958.         self.weapon = 2;
  959.         self.netname = "spikes";
  960.     }
  961.  
  962.     if (self.spawnflags & WEAPON_ROCKET)
  963.     {
  964.         if (self.spawnflags & WEAPON_BIG)
  965.         {
  966.             precache_model ("maps/b_rock1.bsp");
  967.             setmodel (self, "maps/b_rock1.bsp");
  968.             self.aflag = 10;
  969.         }
  970.         else
  971.         {
  972.             precache_model ("maps/b_rock0.bsp");
  973.             setmodel (self, "maps/b_rock0.bsp");
  974.             self.aflag = 5;
  975.         }
  976.         self.weapon = 3;
  977.         self.netname = "rockets";
  978.     }
  979.     
  980.     setsize (self, '0 0 0', '32 32 56');
  981.     StartItem ();
  982. };
  983.  
  984.  
  985. /*
  986. ===============================================================================
  987.  
  988. KEYS
  989.  
  990. ===============================================================================
  991. */
  992.  
  993. void() key_touch =
  994. {
  995. local entity    stemp;
  996. local float        best;
  997.  
  998.     if (other.classname != "player")
  999.         return;
  1000.     if (other.health <= 0)
  1001.         return;
  1002.     if (other.items & self.items)
  1003.         return;
  1004.  
  1005.     sprint (other, "You got the ");
  1006.     sprint (other, self.netname);
  1007.     sprint (other,"\n");
  1008.  
  1009.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1010.     stuffcmd (other, "bf\n");
  1011.     other.items = other.items | self.items;
  1012.  
  1013.     if (!coop)
  1014.     {    
  1015.         self.solid = SOLID_NOT;
  1016.         self.model = string_null;
  1017.     }
  1018.  
  1019.     activator = other;
  1020.     SUB_UseTargets();                // fire all targets / killtargets
  1021. };
  1022.  
  1023.  
  1024. void() key_setsounds =
  1025. {
  1026.     if (world.worldtype == 0)
  1027.     {
  1028.         precache_sound ("misc/medkey.wav");
  1029.         self.noise = "misc/medkey.wav";
  1030.     }
  1031.     if (world.worldtype == 1)
  1032.     {
  1033.         precache_sound ("misc/runekey.wav");
  1034.         self.noise = "misc/runekey.wav";
  1035.     }
  1036.     if (world.worldtype == 2)
  1037.     {
  1038.         precache_sound2 ("misc/basekey.wav");
  1039.         self.noise = "misc/basekey.wav";
  1040.     }
  1041. };
  1042.  
  1043. /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32)
  1044. SILVER key
  1045. In order for keys to work
  1046. you MUST set your maps
  1047. worldtype to one of the
  1048. following:
  1049. 0: medieval
  1050. 1: metal
  1051. 2: base
  1052. */
  1053.  
  1054. void() item_key1 =
  1055. {
  1056.     if (world.worldtype == 0)
  1057.     {
  1058.         precache_model ("progs/w_s_key.mdl");
  1059.         setmodel (self, "progs/w_s_key.mdl");
  1060.         self.netname = "silver key";
  1061.     }
  1062.     else if (world.worldtype == 1)
  1063.     {
  1064.         precache_model ("progs/m_s_key.mdl");
  1065.         setmodel (self, "progs/m_s_key.mdl");
  1066.         self.netname = "silver runekey";
  1067.     }
  1068.     else if (world.worldtype == 2)
  1069.     {
  1070.         precache_model2 ("progs/b_s_key.mdl");
  1071.         setmodel (self, "progs/b_s_key.mdl");
  1072.         self.netname = "silver keycard";
  1073.     }
  1074.     key_setsounds();
  1075.     self.touch = key_touch;
  1076.     self.items = IT_KEY1;
  1077.     setsize (self, '-16 -16 -24', '16 16 32');
  1078.     StartItem ();
  1079. };
  1080.  
  1081. /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32)
  1082. GOLD key
  1083. In order for keys to work
  1084. you MUST set your maps
  1085. worldtype to one of the
  1086. following:
  1087. 0: medieval
  1088. 1: metal
  1089. 2: base
  1090. */
  1091.  
  1092. void() item_key2 =
  1093. {
  1094.     if (world.worldtype == 0)
  1095.     {
  1096.         precache_model ("progs/w_g_key.mdl");
  1097.         setmodel (self, "progs/w_g_key.mdl");
  1098.         self.netname = "gold key";
  1099.     }
  1100.     if (world.worldtype == 1)
  1101.     {
  1102.         precache_model ("progs/m_g_key.mdl");
  1103.         setmodel (self, "progs/m_g_key.mdl");
  1104.         self.netname = "gold runekey";
  1105.     }
  1106.     if (world.worldtype == 2)
  1107.     {
  1108.         precache_model2 ("progs/b_g_key.mdl");
  1109.         setmodel (self, "progs/b_g_key.mdl");
  1110.         self.netname = "gold keycard";
  1111.     }
  1112.     key_setsounds();
  1113.     self.touch = key_touch;
  1114.     self.items = IT_KEY2;
  1115.     setsize (self, '-16 -16 -24', '16 16 32');
  1116.     StartItem ();
  1117. };
  1118.  
  1119.  
  1120.  
  1121. /*
  1122. ===============================================================================
  1123.  
  1124. END OF LEVEL RUNES
  1125.  
  1126. ===============================================================================
  1127. */
  1128.  
  1129. void() sigil_touch =
  1130. {
  1131. local entity    stemp;
  1132. local float        best;
  1133.  
  1134.     if (other.classname != "player")
  1135.         return;
  1136.     if (other.health <= 0)
  1137.         return;
  1138.  
  1139.     centerprint (other, "You got the rune!");
  1140.  
  1141.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1142.     stuffcmd (other, "bf\n");
  1143.     self.solid = SOLID_NOT;
  1144.     self.model = string_null;
  1145.     serverflags = serverflags | (self.spawnflags & 15);
  1146.     self.classname = "";        // so rune doors won't find it
  1147.     
  1148.     activator = other;
  1149.     SUB_UseTargets();                // fire all targets / killtargets
  1150. };
  1151.  
  1152.  
  1153. /*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4
  1154. End of level sigil, pick up to end episode and return to jrstart.
  1155. */
  1156.  
  1157. void() item_sigil =
  1158. {
  1159.     if (!self.spawnflags)
  1160.         objerror ("no spawnflags");
  1161.  
  1162.     precache_sound ("misc/runekey.wav");
  1163.     self.noise = "misc/runekey.wav";
  1164.  
  1165.     if (self.spawnflags & 1)
  1166.     {
  1167.         precache_model ("progs/end1.mdl");
  1168.         setmodel (self, "progs/end1.mdl");
  1169.     }
  1170.     if (self.spawnflags & 2)
  1171.     {
  1172.         precache_model2 ("progs/end2.mdl");
  1173.         setmodel (self, "progs/end2.mdl");
  1174.     }
  1175.     if (self.spawnflags & 4)
  1176.     {
  1177.         precache_model2 ("progs/end3.mdl");
  1178.         setmodel (self, "progs/end3.mdl");
  1179.     }
  1180.     if (self.spawnflags & 8)
  1181.     {
  1182.         precache_model2 ("progs/end4.mdl");
  1183.         setmodel (self, "progs/end4.mdl");
  1184.     }
  1185.     
  1186.     self.touch = sigil_touch;
  1187.     setsize (self, '-16 -16 -24', '16 16 32');
  1188.     StartItem ();
  1189. };
  1190.  
  1191. /*
  1192. ===============================================================================
  1193.  
  1194. POWERUPS
  1195.  
  1196. ===============================================================================
  1197. */
  1198.  
  1199. void() powerup_touch;
  1200.  
  1201.  
  1202. void() powerup_touch =
  1203. {
  1204. local entity    stemp;
  1205. local float        best;
  1206.  
  1207.     if (other.classname != "player")
  1208.         return;
  1209.     if (other.health <= 0)
  1210.         return;
  1211.  
  1212.     sprint (other, "You got the ");
  1213.     sprint (other, self.netname);
  1214.     sprint (other,"\n");
  1215.  
  1216.     if (deathmatch)
  1217.     {
  1218.         self.mdl = self.model;
  1219.         
  1220. //#Harlequin#  Powerup anti-camper respawn
  1221.         if (self.think == ItemFindCampers)
  1222.         {
  1223.             if (self.classname == "item_artifact_super_damage")
  1224.                 self.RESPAWN_TIME = time + 60;
  1225.             else
  1226.                 self.RESPAWN_TIME = time + 60*5;
  1227.         }
  1228.         else
  1229.         {
  1230.             if ((self.classname == "item_artifact_invulnerability") ||
  1231.                 (self.classname == "item_artifact_invisibility"))
  1232.                 self.nextthink = time + 60*5;
  1233.             else
  1234.                 self.nextthink = time + 60;
  1235.             self.think = SUB_regen;
  1236.         }
  1237.     }    
  1238. //#Harlequin#  End of my mods in this section
  1239.  
  1240.     sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1241.     stuffcmd (other, "bf\n");
  1242.     self.solid = SOLID_NOT;
  1243.     other.items = other.items | self.items;
  1244.     self.model = string_null;
  1245.  
  1246. // do the apropriate action
  1247.     if (self.classname == "item_artifact_envirosuit")
  1248.     {
  1249.         other.rad_time = 1;
  1250.         other.radsuit_finished = time + 30;
  1251.     }
  1252.     
  1253.     if (self.classname == "item_artifact_invulnerability")
  1254.     {
  1255.         other.invincible_time = 1;
  1256.         other.invincible_finished = time + 30;
  1257.     }
  1258.     
  1259.     if (self.classname == "item_artifact_invisibility")
  1260.     {
  1261.         other.invisible_time = 1;
  1262.         other.invisible_finished = time + 30;
  1263.     }
  1264.  
  1265.     if (self.classname == "item_artifact_super_damage")
  1266.     {
  1267.         other.super_time = 1;
  1268.         other.super_damage_finished = time + 30;
  1269.     }    
  1270.  
  1271.     activator = other;
  1272.     SUB_UseTargets();                // fire all targets / killtargets
  1273. };
  1274.  
  1275.  
  1276.  
  1277. /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32)
  1278. Player is invulnerable for 30 seconds
  1279. */
  1280. void() item_artifact_invulnerability =
  1281. {
  1282.     self.touch = powerup_touch;
  1283.  
  1284.     precache_model ("progs/invulner.mdl");
  1285.     precache_sound ("items/protect.wav");
  1286.     precache_sound ("items/protect2.wav");
  1287.     precache_sound ("items/protect3.wav");
  1288.     self.noise = "items/protect.wav";
  1289.     setmodel (self, "progs/invulner.mdl");
  1290.     self.netname = "Pentagram of Protection";
  1291.     self.items = IT_INVULNERABILITY;
  1292.     setsize (self, '-16 -16 -24', '16 16 32');
  1293.     StartItem ();
  1294. };
  1295.  
  1296. /*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32)
  1297. Player takes no damage from water or slime for 30 seconds
  1298. */
  1299. void() item_artifact_envirosuit =
  1300. {
  1301.     self.touch = powerup_touch;
  1302.  
  1303.     precache_model ("progs/suit.mdl");
  1304.     precache_sound ("items/suit.wav");
  1305.     precache_sound ("items/suit2.wav");
  1306.     self.noise = "items/suit.wav";
  1307.     setmodel (self, "progs/suit.mdl");
  1308.     self.netname = "Biosuit";
  1309.     self.items = IT_SUIT;
  1310.     setsize (self, '-16 -16 -24', '16 16 32');
  1311.     StartItem ();
  1312. };
  1313.  
  1314.  
  1315. /*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32)
  1316. Player is invisible for 30 seconds
  1317. */
  1318. void() item_artifact_invisibility =
  1319. {
  1320.     self.touch = powerup_touch;
  1321.  
  1322.     precache_model ("progs/invisibl.mdl");
  1323.     precache_sound ("items/inv1.wav");
  1324.     precache_sound ("items/inv2.wav");
  1325.     precache_sound ("items/inv3.wav");
  1326.     self.noise = "items/inv1.wav";
  1327.     setmodel (self, "progs/invisibl.mdl");
  1328.     self.netname = "Ring of Shadows";
  1329.     self.items = IT_INVISIBILITY;
  1330.     setsize (self, '-16 -16 -24', '16 16 32');
  1331.     StartItem ();
  1332. };
  1333.  
  1334.  
  1335. /*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32)
  1336. The next attack from the player will do 4x damage
  1337. */
  1338. void() item_artifact_super_damage =
  1339. {
  1340.     self.touch = powerup_touch;
  1341.  
  1342.     precache_model ("progs/quaddama.mdl");
  1343.     precache_sound ("items/damage.wav");
  1344.     precache_sound ("items/damage2.wav");
  1345.     precache_sound ("items/damage3.wav");
  1346.     self.noise = "items/damage.wav";
  1347.     setmodel (self, "progs/quaddama.mdl");
  1348.     self.netname = "Quad Damage";
  1349.     self.items = IT_QUAD;
  1350.     setsize (self, '-16 -16 -24', '16 16 32');
  1351.     StartItem ();
  1352. };
  1353.  
  1354.  
  1355.  
  1356. /*
  1357. ===============================================================================
  1358.  
  1359. PLAYER BACKPACKS
  1360.  
  1361. ===============================================================================
  1362. */
  1363.  
  1364. void() BackpackTouch =
  1365. {
  1366.     local string    s;
  1367.     local    float    best;
  1368.     local        entity    stemp;
  1369.     
  1370.     if (other.classname != "player")
  1371.         return;
  1372.     if (other.health <= 0)
  1373.         return;
  1374.         
  1375. // if the player was using his best weapon, change up to the new one if better        
  1376.     stemp = self;
  1377.     self = other;
  1378.     best = W_BestWeapon();
  1379.     self = stemp;
  1380.  
  1381. // change weapons
  1382.     other.ammo_shells = other.ammo_shells + self.ammo_shells;
  1383.     other.ammo_nails = other.ammo_nails + self.ammo_nails;
  1384.     other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1385.     other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1386.  
  1387.     other.items = other.items | self.items;
  1388.     
  1389.     bound_other_ammo ();
  1390.  
  1391.     sprint (other, "You get ");
  1392.  
  1393.     if (self.ammo_shells)
  1394.     {
  1395.         s = ftos(self.ammo_shells);
  1396.         sprint (other, s);
  1397.         sprint (other, " shells  ");
  1398.     }
  1399.     if (self.ammo_nails)
  1400.     {
  1401.         s = ftos(self.ammo_nails);
  1402.         sprint (other, s);
  1403.         sprint (other, " nails ");
  1404.     }
  1405.     if (self.ammo_rockets)
  1406.     {
  1407.         s = ftos(self.ammo_rockets);
  1408.         sprint (other, s);
  1409.         sprint (other, " rockets  ");
  1410.     }
  1411.     if (self.ammo_cells)
  1412.     {
  1413.         s = ftos(self.ammo_cells);
  1414.         sprint (other, s);
  1415.         sprint (other, " cells  ");
  1416.     }
  1417.     
  1418.     sprint (other, "\n");
  1419. // backpack touch sound
  1420.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1421.     stuffcmd (other, "bf\n");
  1422.  
  1423. // change to a better weapon if appropriate
  1424.     if ( other.weapon == best )
  1425.     {
  1426.         stemp = self;
  1427.         self = other;
  1428.         self.weapon = W_BestWeapon();
  1429.         self = stemp;
  1430.     }
  1431.  
  1432.     
  1433.     remove(self);
  1434.     
  1435.     self = other;
  1436.     W_SetCurrentAmmo ();
  1437. };
  1438.  
  1439. /*
  1440. ===============
  1441. DropBackpack
  1442. ===============
  1443. */
  1444. void() DropBackpack =
  1445. {
  1446.     local entity    item;
  1447.  
  1448.     if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
  1449.         return;    // nothing in it
  1450.  
  1451.     item = spawn();
  1452.     item.origin = self.origin - '0 0 24';
  1453.     
  1454.     item.items = self.weapon;
  1455.  
  1456.     item.ammo_shells = self.ammo_shells;
  1457.     item.ammo_nails = self.ammo_nails;
  1458.     item.ammo_rockets = self.ammo_rockets;
  1459.     item.ammo_cells = self.ammo_cells;
  1460.  
  1461.     item.velocity_z = 300;
  1462.     item.velocity_x = -100 + (random() * 200);
  1463.     item.velocity_y = -100 + (random() * 200);
  1464.     
  1465.     item.flags = FL_ITEM;
  1466.     item.solid = SOLID_TRIGGER;
  1467.     item.movetype = MOVETYPE_TOSS;
  1468.     setmodel (item, "progs/backpack.mdl");
  1469.     setsize (item, '-16 -16 0', '16 16 56');
  1470.     item.touch = BackpackTouch;
  1471.     
  1472.     item.nextthink = time + 120;    // remove after 2 minutes
  1473.     item.think = SUB_Remove;
  1474. };
  1475.